在上個篇章Day-17已經又提及Pod,也知道Pod為Kubernetes cluster當中最小的執行單位,然後一個Pod當中會有著一個或多個Containers,這些Containers彼此共享著這個pod的資源與端口port,並且互相能以localhost找到其他pod所expose的port。
在這章節除了詳細介紹Pod之外,還會介紹與Pod有著相當淵源的ReplicaSet與Deployment,那我們開始吧!
Pod又稱豆莢,中間的小豆豆指的就是容器,一個Pod能有一到多個容器,所以Pod是由一組耦合高的容器們組成的容器組,Pod中的所有Containers在共享環境中運行。而這裡的共享環境也衍生出以下幾個特點:
Pod也與人一樣有著生老病死,並且Pod與先前介紹的容器一樣是個臨時性的實例,所以不會長期的存在。Pod在被創立時會被予以一個唯一的ID,就像人的身分證字號一樣,並且在創立後被調度到特定節點直到被終止或被刪除前不同地運行著工作。
Pod有著五個不同的status,分別為Pending、Running、Succeeded、Failed與Unknow。
Status | Description |
---|---|
Pending | Pod 已被 Kubernetes 系统接受,但有一或多個容器尚未被創。此階段包含著正在等待Docker image被下載、等待Container被建立與等待著Pod被調度...等事件。 |
Running | Pod 已經綁定到了某個節點,Pod 中所有的容器都已被創建。至少有一個容器仍在運行,或者正處於啟動或重啟狀態。 |
Succeeded | Pod 中的所有容器都已成功終止,並且不會再重啟。 |
Failed | Pod 中的所有容器都已終止,並且至少有一個容器是因為失敗終止。也就是說,容器以非0 狀態退出或者被系統終止。 |
Unknow | 因為某些原因無法取得Pod 的狀態。這種情況通常是因為與Pod 所在主機通信失敗。 |
Tips: 如果某節點死掉或者與集群中其他節點失聯,Kubernetes會實施一種策略,將失去的節點上運行的所有Pod的phase設置為Failed。
除了Pod之外,Kubernetes亦會追蹤Pod內每個容器的狀態,一但Scheduler決定將新的Pod分配給指定Node時,Kubelet會開始為該Pod創內裡面所屬的Containers,這些Containers會有著三種不同的狀態,分別為Waiting、Running與Terminated。
至於想要觀察Pod內部容器狀況的話,能夠透過以下指令來獲得資訊。
$ kubectl describe <pod_name/pod_id> -n <namespace>
若不指定namespace則預設為default。
Status | Description |
---|---|
Waiting | 表示Container仍正在進行啟動所需操作,像是 pull docker image、從Secret取得資料、掛載Volume..等。 |
Running | 表示容器正在執行狀態並且沒有問題發生。如果配置了postStart回調,那麼該回調已經執行完成。如果配置了postStart回調,那麼該回調已經執行完成。 |
Terminated | 表示容器開始正常執行,並且已正常結束或者因某些原因失敗。如果容器配置了preStop回調,則該回調會在容器進入Terminated 狀態之前執行。 |
Kubernetes中的資源創建都是以yaml檔來撰寫,那這邊我們就以下面的範例進行解說。
nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
kubernetes api version,若versions在1.9以前則使用apps/v1beta2
Kuberentes通常以kind來分辨此yaml的resource種類,像是pod、service、secret....等
這邊主要填寫該pod的訊息資訊,像是Pod的name與Pod的label亦或是annotation等。
這邊則開始制定該Pod的規格,包含裡頭所擁有的containers,containers分別的名稱、Image、port到掛載的資源與重啟策略、健康檢查...等都包含在此。
那我們現在就以上面的例子來進行部署!
我們先來看一下現行環境與Default Namespace當中,運行的Pod情況。
$ kubectl get pod
No resources found in default namespace.
那我們就來部署了
$ kubectl apply -f nginx.yaml
pod/nginx created
部署完成後我們再來看一下目前的情況
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 44s
可以看到我們的Pod開始運作了,那這時我們來看一下GKE的後台
最後確認到nginx pod確實部署到GKE上並且狀態為Running,大功告成。
image: ghjjhg567/sif:latest
ports:
- containerPort: 8100
port bind in the pod,其他containers可在同一pod內用localhost:80來找到它。同時也可以透過連接該pod的service來找到它。
imagePullPolicy: Always
有Always、IfNotPresent、Never三種選項
command: ["/usr/src/app/docker_entrypoint.sh"]
類似於Docker中的Entrypoint,每次啟動Container時會最先執行的指令。
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
用來設定container最低需求與最高限制的使用資源。
readinessProbe:
httpGet:
path: /v1/hc
port: 8100
initialDelaySeconds: 5
periodSeconds: 10
健康檢查,並且可以設定web protocol、你health check的endpoint與健康檢查的時間間隔..等設定。P.S 如果健康檢查不過,該Pod是不會變成Running狀態的。
envFrom:
- configMapRef:
name: django-config
- configMapRef:
name: maria-db-config
- configMapRef:
name: rabbit-mq-config
可以透過像是configMap或secrets的k8s配置文件,來新增該container的環境變數。
Tips: configMap與secret等在後面篇章會提到。
除了這些外,當然還有很多Template Key&Value,但由於篇幅關係,如果還有其他需求再請去參照官網 https://kubernetes.io/docs/tasks/configure-pod-container/
ReplicaSet的目的是維護一組在任何時候都處於Running狀態的Pod集合,因此,他通常用來穩定維護一定數量的Replicas,確保Pod隨時隨地都在運行。
透過Pod上的metadata.ownerReferences連接到選定的Pod,並獲得所選定Pod的ReplicaSet相關訊息。透過訊息得知Pod Set目前的狀態,並依據該狀態進行操作
雖然可以透過template type(kind)為ReplicaSet來單獨使用它,但由於它主要是被Deployment用作協調刪除與創建Pod的控制機制,並且在使用Deployment時,不需要特別去管理它,也因此會選擇在使用Deployment時宣告居多。
當你需要確保任何時間點都有著指定數量的Pod正在運行著時,就會需要ReplicaSet。然而Deployment是一個更高層級的概念,並且Deployment管理著ReplicaSet,也因此會建議直接使用Deployment就好。
ReplicaSet的yaml階層主要由四大部分組成:
nginx_replicaSet.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
labels:
name: nginx
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
我們接下來執行一下nginx_replicaSet.yaml吧
$ kubectl apply -f nginx_replicaSet.yaml
replicaset.apps/nginx created
接下來觀察一下replicaSet與Pod情形
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-76hcb 1/1 Running 0 7m15s
nginx-ctt4q 1/1 Running 0 7m15s
nginx-tx5j9 1/1 Running 0 7m15s
kubectl get replicaset
NAME DESIRED CURRENT READY AGE
nginx 3 3 3 7m32s
OK, ReplicaSet與Pod都正常運作,那最後我們看一下GKE上工作負載的情況!
確實有了ReplicaSet,並且裡頭的Pod也都運作著,到這邊我們就大功告成了!
這章節我們更深入的談討了Pod,並且以nginx.yaml為例介紹了Pod template基本的撰寫與代表意義,也透過GKE部署了它。之後也介紹了確保Pod Set運行的ReplicaSet,並且也一樣帶一個範例解說。
但礙於篇幅關係,我會將Deployment與Deployment的撰寫放在這個主題的下篇,也請初入Kubernete的大家期待一下,謝謝。
https://kubernetes.io/docs/concepts/workloads/pods/
https://www.ibm.com/cloud/architecture/content/course/kubernetes-101/deployments-replica-sets-and-pods